package cn.maihe.elg.operation.service.invoice;

import cn.maihe.elg.operation.model.enums.InvoiceReversalFlag;
import cn.maihe.elg.operation.model.enums.InvoiceStatusEnum;
import cn.maihe.elg.operation.model.vo.invoice.InvoiceReportQueryVO;
import cn.maihe.elg.operation.model.vo.order.ListAcceptOrderDO;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.InvoiceInfoDO;
import cn.maihe.elg.operation.repository.entity.InvoiceInfoDOCondition;
import cn.maihe.elg.operation.repository.entity.InvoiceInfoVo;
import cn.maihe.elg.operation.repository.mapper.AcceptOrderInfoMapper;
import cn.maihe.elg.operation.repository.mapper.InvoiceInfoMapper;
import cn.maihe.elg.operation.service.BaseDaoService;
import cn.maihe.framework.starter.base.sql.PageBo;
import cn.maihe.framework.starter.mybatis.dao.MybatisDaoImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 开票信息服务
 * @Author WJH
 * @Date 2021/03/25
 */
@Service
public class InvoiceInfoService extends BaseDaoService<InvoiceInfoDO> {

    @Resource
    private InvoiceInfoMapper invoiceInfoMapper;
    @Resource
    private AcceptOrderInfoMapper acceptOrderInfoMapper;

    public PageBo<InvoiceInfoDO> selectPageBySql(int pageNo, int pageSize, String gmtCreateRange, InvoiceInfoVo vo) {
        Map<String, Object> paramsMap = toMapAndAddParams(vo);
        if (StringUtils.isNotBlank(gmtCreateRange)) {
            String[] rangeAy = gmtCreateRange.split(",");
            if (rangeAy.length > 1) {
                paramsMap.put("startGmtCreate", rangeAy[0] + " 00:00:00");
                paramsMap.put("endGmtCreate", rangeAy[1] + " 23:59:59");
            }
        }
        return this.selectPageBySql("selectInvoiceList", "selectInvoiceCount", paramsMap, pageNo, pageSize);
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(InvoiceInfoDO invoiceInfoDO, AcceptOrderInfoDO acceptOrderInfoDO) {
        InvoiceInfoDO dbInvoiceInfo = this.selectById(invoiceInfoDO.getId());
        if (dbInvoiceInfo != null) {
            this.updateById(invoiceInfoDO);
        } else {
            invoiceInfoMapper.insert(invoiceInfoDO);
        }
        acceptOrderInfoMapper.updateById(acceptOrderInfoDO);
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdate(InvoiceInfoDO invoiceInfoDO, AcceptOrderInfoDO acceptOrderInfoDO) {
        InvoiceInfoDO dbInvoiceInfo = this.selectOne(InvoiceInfoDOCondition.builder().andAcceptOrderNosEq(acceptOrderInfoDO.getAcceptOrderNo()).build());
        if (dbInvoiceInfo != null) {
            invoiceInfoDO.setId(dbInvoiceInfo.getId());
            this.updateById(invoiceInfoDO);
        } else {
            invoiceInfoMapper.insert(invoiceInfoDO);
        }
    }


    public List<ListAcceptOrderDO> listInvoiceReportDownload(InvoiceReportQueryVO vo) {
        Map<String, Object> paramsMap = toMapAndAddParams(vo);
        //出函时间
        if (!CollectionUtils.isEmpty(vo.getGuaranteeTimeRange())) {
            String[] rangeAy = vo.getGuaranteeTimeRange().toArray(new String[0]);
            paramsMap.put("startGuaranteeTime", rangeAy[0] + " 00:00:00");
            paramsMap.put("endGuaranteeTime", rangeAy[1] + " 23:59:59");
        }
        return MybatisDaoImpl.of(AcceptOrderInfoMapper.class).selectListBySql("selectAcceptOrderList", paramsMap);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void failHandle(InvoiceInfoDO invoiceInfoDO) {
        boolean isReversal = (invoiceInfoDO.getInvoiceType() != null && invoiceInfoDO.getInvoiceType() == 2) ? true : false;
        if (isReversal) {
            InvoiceInfoDO updateOrigInvoiceInfo = InvoiceInfoDO.builder().invoiceReversalFlag(InvoiceReversalFlag.FAILURE.getFlag()).build();
            this.update(updateOrigInvoiceInfo, InvoiceInfoDOCondition.builder().andInvoiceReversalIdEq(invoiceInfoDO.getId()).andInvoiceReversalFlagEq(InvoiceReversalFlag.PROCESSING.getFlag()).build());
        } else {
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("invoiceId", invoiceInfoDO.getId());
            MybatisDaoImpl.of(AcceptOrderInfoMapper.class).updateBySql("invoiceFail", paramsMap);
        }
    }


    /**
     * 退保审核通过设置发票冲红标识为待冲红
     */
    public void updateInvoiceReversal(Long invoiceId) {
        if (invoiceId != null) {
            InvoiceInfoDOCondition condition = InvoiceInfoDOCondition.builder().andIdEq(invoiceId)
                    .andInvoiceReversalFlagEq(InvoiceReversalFlag.UNDO.getFlag());
            InvoiceInfoDO updateDo = InvoiceInfoDO.builder().invoiceReversalFlag(InvoiceReversalFlag.WAITING.getFlag()).build();
            this.update(updateDo, condition.build());
        }
    }

    public void doInvoiceReversal(InvoiceInfoDO invoiceInfo) {
        if (invoiceInfo == null || InvoiceStatusEnum.INVOICED.getValue() != invoiceInfo.getStatus()) {
            throw new RuntimeException("原发票记录为空或原发票状态不为已开票,不能发起发票冲红操作");
        }


    }
}
